from django.db.models import Q
from django.core.paginator import Paginator
from rest_framework.viewsets import ViewSet

from utils.params_filter import set_task_id
from .models import *
from .serializers import *
from utils.response import *
from utils.params_filter import allow_edit, get_page
from .lib.request_handler import async_request_tool, request_tool
from .lib.scheduler_core import scheduler, SchedulerThread

from apscheduler.jobstores.base import JobLookupError


class CreateJobReortViewSet(ViewSet):
	authentication_classes = []

	def create(self, request):
		allow = ['case_id', 'task_id', 'expect', 'actual', 'response_data']
		data = allow_edit(allow, request)
		JobReport.objects.create(**data)
		return SuccessResponse()


class JobReportViewSet(ViewSet):
	serializers_class = JobReportSerializer

	def list(self, request):
		data = get_page(request, JobReport, JobReportSerializer)
		return SuccessResponse(data=data, msg='调用成功')


class JobManageViewSet(ViewSet):
	# 开启调度器
	def start_scheduler(self, request):
		state = scheduler.state
		if state == 1:
			return SuccessResponse(msg='调度器已启动或未关闭')
		else:
			scheduler_thread = SchedulerThread(scheduler, 'scheduler_thread')
			scheduler_thread.start()
			return SuccessResponse(msg='调度器启动成功')

	# 关闭调度器
	def stop_scheduler(self, request):
		# 获取当前调度器状态
		state = scheduler.state
		if state == 0:
			msg = '调度器已关闭或未开启'
		else:
			msg = '调度器关闭成功'
			scheduler.shutdown_scheduler()
		return SuccessResponse(msg=msg)

	# 启动任务
	def start_job(self, request):
		if scheduler.state == 0:
			return ErrorResponse(msg='调度器未启用')
		case_id = request.data.get('caseId')
		if not case_id:
			return ErrorResponse(msg='请求参数错误')
		case = ApiCase.objects.filter(id=case_id, deleted=False)
		if not case:
			return ErrorResponse(msg='用例不存在或已删除')
		tmp_case = case.first()
		url = tmp_case.api.project.host + tmp_case.api.url
		params = tmp_case.param
		trigger = tmp_case.job_type.dict_value
		trigger_args = tmp_case.job_cron
		task_id = set_task_id(tmp_case)

		if trigger == 'interval':
			trigger_args = {
				"seconds": int(trigger_args)
			}

		# 调度器参数
		job_args = {
			'url': url,
			'method': tmp_case.request_type.dict_value,
			'headers': json.loads(tmp_case.headers.replace("\'", "\"")),
			'params': params,
			'expect_type': tmp_case.expect_type.dict_value,
			'expect': tmp_case.expect,
			'task_id': task_id,
			'case_id': case_id
		}

		# 任务表参数
		job_data = {
			'url': url,
			'params': params,
			'case_id': case_id,
			'trigger': trigger,
			'job_cron': trigger_args,
			'task_id': task_id
		}

		job = Job.objects.filter(case_id=case_id, deleted=False).first()
		if not job:
			Job.objects.create(**job_data)
			case.update(task_id=task_id, status=1)
			scheduler.add_job(func=async_request_tool, trigger=trigger, trigger_args=trigger_args, job_id=task_id,
							  args=(job_args,))
			return SuccessResponse(msg='开始任务')
		else:
			try:
				scheduler.resume_job(task_id)
				case.update(status=1)
				return SuccessResponse(msg='任务已启动')
			except JobLookupError:
				scheduler.add_job(func=async_request_tool, trigger=trigger, trigger_args=trigger_args, job_id=task_id,
								  args=(job_args,))
				return SuccessResponse(msg='开始任务')

	# 暂停或恢复任务
	def pause_or_resume_job(self, request):
		"""
		:param int caseId: 用例id
		:param str action: 动作 pause 暂停暂停 resume 恢复作业
		"""
		case_id = request.query_params.get('caseId')
		action = request.query_params.get('action')
		if not case_id or not action:
			return ErrorResponse(msg='请求参数错误')

		if scheduler.state == 0:
			return ErrorResponse(msg='调度器未启用')
		case = ApiCase.objects.filter(id=case_id, deleted=False)
		if not case:
			return ErrorResponse(msg='任务不存在或已删除')
		task_id = case.first().task_id
		# 暂停作业
		if action == 'pause':
			try:
				scheduler.pause_job(task_id)
				case.update(status=2)
			except JobLookupError:
				return ErrorResponse(msg=f'任务ID: {task_id}不存在')
			return SuccessResponse(msg='任务已停止')
		# 恢复作业
		elif action == 'resume':
			try:
				scheduler.resume_job(task_id)
				case.update(status=1)
			except JobLookupError:
				return ErrorResponse(msg=f'任务ID: {task_id}不存在')
			return SuccessResponse(msg='任务已恢复')
		else:
			return ErrorResponse(msg='请求参数错误')

	def del_all_job(self, request):
		scheduler.remove_all_jobs()
		Job.objects.filter(deleted=False).update(deleted=True)
		return SuccessResponse(msg='请求成功')

	def job_list(self, request):
		serializer = JobSerializer(Job.objects.filter(deleted=False), many=True)
		return SuccessResponse(data=({'list': serializer.data}), msg='调用成功')

	def get_jobs(self, request):
		print(scheduler.get_jobs()[0])
		print(scheduler.run)
		return SuccessResponse()

	def run_now(self, request):
		case_id = request.query_params.get('caseId')
		tmp_case = ApiCase.objects.filter(id=case_id, deleted=False).first()
		url = tmp_case.api.project.host + tmp_case.api.url
		params = tmp_case.param
		job_args = {
			'url': url,
			'method': tmp_case.request_type.dict_value,
			'headers': json.loads(tmp_case.headers.replace("\'", "\"")),
			'params': params,
			'expect_type': tmp_case.expect_type.dict_value,
			'expect': tmp_case.expect,
			'case_id': case_id
		}
		data = request_tool(job_args)
		return SuccessResponse(data=data)
